package com.mall.order.services;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mall.order.OrderQueryService;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.constants.OrderConstants;
import com.mall.order.converter.OrderConverter;
import com.mall.order.dal.entitys.*;
import com.mall.order.dal.persistence.OrderItemMapper;
import com.mall.order.dal.persistence.OrderMapper;
import com.mall.order.dal.persistence.OrderShippingMapper;
import com.mall.order.dal.persistence.StockMapper;
import com.mall.order.dto.*;
import com.mall.order.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.common.rowbounds.SelectByExampleRowBoundsMapper;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 *  cskaoyan
 */
@Slf4j
@Component
@Service
public class OrderQueryServiceImpl implements OrderQueryService {

    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderItemMapper orderItemMapper;
    @Autowired
    StockMapper stockMapper;
    @Autowired
    OrderShippingMapper orderShippingMapper;

    @Override
    public OrderListResponse orderList(OrderListRequest request) {
        OrderListResponse response = new OrderListResponse();

        try {
            request.requestCheck();
            //设置orderDetailInfo
            PageHelper.startPage(request.getPage(),request.getSize());
            ArrayList<OrderDetailInfo> orderDetailInfos = new ArrayList<>();

            //查询order
            Example orderExample = new Example(Order.class);
            if(request.getSort() != null){
                orderExample.setOrderByClause(request.getSort());
            }

            orderExample.createCriteria().andEqualTo("userId",request.getUserId());
            orderExample.setOrderByClause("update_time DESC");
            List<Order> orders = orderMapper.selectByExample(orderExample);
            PageInfo<Order> orderPageInfo = new PageInfo<>(orders);
            long total = orderPageInfo.getTotal();
            response.setTotal(total);

            //通过order查询detail
            for (Order orderInfo : orders) {
                OrderDetailInfo orderDetailInfo = new OrderDetailInfo();
                BeanUtils.copyProperties(orderDetailInfo,orderInfo);


                //给里面的orderItemDto赋值
                ArrayList<OrderItemDto> orderItemDtos = getOrderItemDtos(orderInfo.getOrderId());
                orderDetailInfo.setOrderItemDto(orderItemDtos);
                orderDetailInfos.add(orderDetailInfo);
            }
            response.setData(orderDetailInfos);
            response.setMsg(OrderRetCode.SUCCESS.getMessage());
            response.setCode(OrderRetCode.SUCCESS.getCode());
        } catch (Exception e) {
            e.printStackTrace();
            response.setCode(OrderRetCode.PIPELINE_RUN_EXCEPTION .getCode());
            response.setMsg("参数校验失败");
        }
        return response;
    }

    private ArrayList<OrderItemDto> getOrderItemDtos(String orderId) throws IllegalAccessException, InvocationTargetException {
        Example example = new Example(OrderItem.class);
        example.createCriteria().andEqualTo("orderId",orderId);
        List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
        ArrayList<OrderItemDto> orderItemDtos = new ArrayList<>();
        for (OrderItem orderItem : orderItems) {
            OrderItemDto orderItemDto = new OrderItemDto();
            BeanUtils.copyProperties(orderItemDto,orderItem);
            orderItemDtos.add(orderItemDto);
        }
        return orderItemDtos;
    }

    @Override
    public OrderDetailResponse1 orderDetail(OrderDetailRequest request) {
        OrderDetailResponse1 response = new OrderDetailResponse1();

        try {
            request.requestCheck();
            //查询订单
            Order order = orderMapper.selectByPrimaryKey(request.getOrderId());
            response.setOrderTotal(order.getPayment());
            response.setOrderStatus(order.getStatus());
            response.setUserId(order.getUserId());
            response.setUserName(order.getBuyerNick());

            //收获信息
            OrderShipping orderShipping = orderShippingMapper.selectByPrimaryKey(request.getOrderId());
            response.setTel(orderShipping.getReceiverPhone());
            response.setStreetName(orderShipping.getReceiverAddress());

            //商品订单信息
            ArrayList<OrderItemDto> orderItemDtos = getOrderItemDtos(request.getOrderId());
            response.setGoodsList(orderItemDtos);
            response.setMsg(OrderRetCode.SUCCESS.getMessage());
            response.setCode(OrderRetCode.SUCCESS.getCode());
        } catch (Exception e) {
            e.printStackTrace();
            response.setCode(OrderRetCode.PIPELINE_RUN_EXCEPTION .getCode());
            response.setMsg("参数校验失败");
        }
        return response;
    }


    @Transactional
    @Override
    public CancelOrderResponse orderCancel(CancelOrderRequest request) {
        CancelOrderResponse response = new CancelOrderResponse();
        try {
            request.requestCheck();

            //更新order
            Order record = new Order();
            record.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
            Example example = new Example(Order.class);
            example.createCriteria().andEqualTo("orderId",request.getOrderId());
            int affectedRows1 = orderMapper.updateByExampleSelective(record, example);
            //库存解锁
            orderItemMapper.updateStockStatus(2,request.getOrderId());

            //更新stock
            updateStock(request.getOrderId());

            response.setMsg(OrderRetCode.SUCCESS.getMessage());
            response.setCode(OrderRetCode.SUCCESS.getCode());
        } catch (Exception e) {
            e.printStackTrace();
            response.setCode(OrderRetCode.PIPELINE_RUN_EXCEPTION .getCode());
            response.setMsg("参数校验失败");
        }
        return response;
    }

    private void updateStock(String orderId) {
        //获取锁定的商品
        Example orderItemExample = new Example(OrderItem.class);
        orderItemExample.createCriteria().andEqualTo("orderId",orderId);
        List<OrderItem> orderItems = orderItemMapper.selectByExample(orderItemExample);
        for (OrderItem orderItem : orderItems) {
            //stock更新
            Stock stock = new Stock();
            stock.setLockCount(-orderItem.getNum());
            stock.setStockCount(orderItem.getNum().longValue());
            stock.setItemId(orderItem.getItemId());
            stockMapper.updateStock(stock);
        }
    }

    @Transactional
    @Override
    public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {
        DeleteOrderResponse response = new DeleteOrderResponse();
        try{
            request.requestCheck();
            //如果用户未付款，删除订单，则需要更新stock,释放库存
            Order o = orderMapper.selectByPrimaryKey(request.getOrderId());
            if(o.getStatus() == 0){
                updateStock(request.getOrderId());
            }

            //删除order
            Order order = new Order();
            order.setOrderId(request.getOrderId());
            orderMapper.delete(order);
            //删除orderItem表
            Example example = new Example(Order.class);
            example.createCriteria().andEqualTo("orderId",request.getOrderId());
            orderItemMapper.deleteByExample(example);

            //删除orderShipping表
            OrderShipping orderShipping = new OrderShipping();
            orderShipping.setOrderId(request.getOrderId());
            orderShippingMapper.delete(orderShipping);

            response.setMsg(OrderRetCode.SUCCESS.getMessage());
            response.setCode(OrderRetCode.SUCCESS.getCode());


        }catch (Exception e){
            e.printStackTrace();
            log.error("OrderQueryServiceImpl.deleteOrder Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }
}
